﻿#include "GUIGlobalFrequencyDomainDialog.h"
#include "ui_GUIGlobalFrequencyDomainDialog.h"

#include "FITK_Kernel/FITKCore/FITKActionOperator.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppSettings.h" 
#include "FITK_Component/FITKAcousticsPhysics/FITKGlobalFrequencyDomain.h"

namespace GUI
{
    GUIGlobalFrequencyDomainDialog::GUIGlobalFrequencyDomainDialog(Acoustics::FITKGlobalFrequencyDomain* globalFrequencyDomain, Core::FITKActionOperator* oper, QWidget *parent) :
        GUIDialogBase(parent),
        _globalFrequencyDomain(globalFrequencyDomain),
        _oper(oper),
        _ui(new Ui::GUIGlobalFrequencyDomainDialog)
    {
        _ui->setupUi(this);
        // 设置对话框关闭时自动删除
        setAttribute(Qt::WA_DeleteOnClose);
        //去掉问号
        Qt::WindowFlags flags = windowFlags();
        flags &= ~Qt::WindowContextHelpButtonHint;
        setWindowFlags(flags);
        //界面设置限制
        _ui->radioButton_Constant->setEnabled(false);
        _ui->radioButton_Exact->setEnabled(false);
        _ui->lineEdit_Bandwidth->setValidator(new QRegExpValidator(QRegExp("^(\\d+(\\.\\d+)?)$")));
        _ui->lineEdit_EndFreq->setValidator(new QRegExpValidator(QRegExp("^(\\d+(\\.\\d+)?)$")));
        _ui->lineEdit_StartFreq->setValidator(new QRegExpValidator(QRegExp("^(\\d+(\\.\\d+)?)$")));
        _ui->lineEdit->setValidator(new QRegExpValidator(QRegExp("^[1-9][0-9]{1,3}$")));
        //初始化
        this->init();
    }

    GUIGlobalFrequencyDomainDialog::~GUIGlobalFrequencyDomainDialog()
    {
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
    }

    void GUIGlobalFrequencyDomainDialog::init()
    {
        if (!_globalFrequencyDomain)return;
        _ui->tabWidget->tabBar()->hide();
        //获取数据
        Acoustics::FITKGlobalFrequencyDomain::DomainType type = _globalFrequencyDomain->getDomainType();
        double startFreq = _globalFrequencyDomain->getStartFrequence();
        double endFreq = _globalFrequencyDomain->getEndFrequence();
        double bandWidth = _globalFrequencyDomain->getBandWidth();
        int num = _globalFrequencyDomain->getOctaveNum();
        //设置界面
        if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandardOctave)
            _ui->radioButton_StandOct->setChecked(true);
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandard1Of3rdOctave)
            _ui->radioButton_13rdStandOct->setChecked(true);
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTExact1OfnthOctave)
            _ui->radioButton_Exact->setChecked(true);
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTConstantBandWidth)
            _ui->radioButton_Constant->setChecked(true);
        int index = _ui->comboBox_StartFreq->findText(QString::number(startFreq));
        _ui->comboBox_StartFreq->setCurrentIndex(index);
        index = _ui->comboBox_EndFreq->findText(QString::number(endFreq));
        _ui->comboBox_EndFreq->setCurrentIndex(index);
        _ui->lineEdit_StartFreq->setText(QString::number(startFreq));
        _ui->lineEdit_EndFreq->setText(QString::number(endFreq));
        _ui->lineEdit_Bandwidth->setText(QString::number(bandWidth));
        _ui->lineEdit->setText(QString::number(num));
    }

    void GUIGlobalFrequencyDomainDialog::on_pushButton_Cancel_clicked()
    {
        this->reject();
    }

    void GUIGlobalFrequencyDomainDialog::on_pushButton_OK_clicked()
    {
        if (!_globalFrequencyDomain) return;
        //获取界面数据
        Acoustics::FITKGlobalFrequencyDomain::DomainType type = Acoustics::FITKGlobalFrequencyDomain::DomainType::DTNone;
        if (_ui->radioButton_StandOct->isChecked())
            type = Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandardOctave;
        else if(_ui->radioButton_13rdStandOct->isChecked())
            type = Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandard1Of3rdOctave;
        else if (_ui->radioButton_Exact->isChecked())
            type = Acoustics::FITKGlobalFrequencyDomain::DomainType::DTExact1OfnthOctave;
        else if (_ui->radioButton_Constant->isChecked())
            type = Acoustics::FITKGlobalFrequencyDomain::DomainType::DTConstantBandWidth;
        double startFreq = 0.0, endFreq = 0.0;
        if (_ui->tabWidget->currentIndex() == 0)
        {
            startFreq = _ui->comboBox_StartFreq->currentText().toDouble();
            endFreq = _ui->comboBox_EndFreq->currentText().toDouble();
        }
        else
        {
            startFreq = _ui->lineEdit_StartFreq->text().toDouble();
            endFreq = _ui->lineEdit_EndFreq->text().toDouble();
        }
        double bandWidth = _ui->lineEdit_Bandwidth->text().toDouble();
        int num = _ui->lineEdit->text().toInt();
        //设置数据
        _globalFrequencyDomain->setDomainType(type);
        _globalFrequencyDomain->setStartFrequence(startFreq);
        _globalFrequencyDomain->setEndFrequence(endFreq);
        _globalFrequencyDomain->setBandWidth(bandWidth);
        _globalFrequencyDomain->setOctaveNum(num);
        this->accept();
    }

    void GUIGlobalFrequencyDomainDialog::on_lineEdit_textChanged(const QString &str)
    {
        if (!_ui->radioButton_Exact->isChecked())return;
        QStringList freq;
        //默认值频率是1000
        const double f0 = 1000;
        double num = str.toDouble();
        const double n = _ui->lineEdit->text().toDouble();
        freq << "1000";
        int i = -1;
        double fc = f0;
        //小于1000的部分
        while (fc > 1.25)
        {
            fc = pow(2.0, i / n)*f0;
            freq.insert(0, QString::number(fc));
            i--;
        }
        //大于1000的部分
        i = 1; fc = f0;
        while (fc < 160000)
        {
            fc = pow(2.0, i / n)*f0;
            freq.append(QString::number(fc));
            i++;
        }
        //更新开始频谱与终止频谱数据
        _ui->comboBox_StartFreq->clear();
        _ui->comboBox_StartFreq->addItems(freq);
        _ui->comboBox_StartFreq->update();
        _ui->comboBox_EndFreq->clear();
        _ui->comboBox_EndFreq->addItems(freq);
        _ui->comboBox_EndFreq->update();
        //设置界面数据
        if (_ui->comboBox_EndFreq->count() != 0)
            _ui->comboBox_EndFreq->setCurrentIndex(_ui->comboBox_EndFreq->count() - 1);
        if (_ui->comboBox_StartFreq->count() != 0)
            _ui->comboBox_StartFreq->setCurrentIndex(0);
    }

    void GUIGlobalFrequencyDomainDialog::on_comboBox_StartFreq_currentIndexChanged(int index)
    {
        //屏蔽信号发出
        _ui->comboBox_EndFreq->blockSignals(true);
        //获取开始频率，终止频率
        double startFreq = _ui->comboBox_StartFreq->currentText().toDouble();
        double endFreq = _ui->comboBox_EndFreq->currentText().toDouble();
        //开始频率要小于终止频率
        if (endFreq < startFreq)
            _ui->comboBox_EndFreq->setCurrentIndex(index);
        //恢复信号发出
        _ui->comboBox_EndFreq->blockSignals(false);
    }

    void GUIGlobalFrequencyDomainDialog::on_comboBox_EndFreq_currentIndexChanged(int index)
    {
        //屏蔽信号发出
        _ui->comboBox_StartFreq->blockSignals(true);
        //获取开始频率，终止频率
        double startFreq = _ui->comboBox_StartFreq->currentText().toDouble();
        double endFreq = _ui->comboBox_EndFreq->currentText().toDouble();
        //开始频率要小于终止频率
        if (endFreq < startFreq)
            _ui->comboBox_StartFreq->setCurrentIndex(index);
        //恢复信号发出
        _ui->comboBox_StartFreq->blockSignals(false);
    }

    void GUIGlobalFrequencyDomainDialog::on_radioButton_StandOct_toggled(bool checkState)
    {
        Q_UNUSED(checkState);
        if (!checkState) return;
        _ui->tabWidget->setCurrentIndex(0);
        _ui->lineEdit->setEnabled(false);
        _ui->lineEdit_Bandwidth->setEnabled(false);
        this->initStartFreqComboBox(Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandardOctave);
        this->initEndFreqComboBox(Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandardOctave);
        //设置界面数据
        if (_ui->comboBox_EndFreq->count() != 0)
            _ui->comboBox_EndFreq->setCurrentIndex(_ui->comboBox_EndFreq->count() - 1);
        if (_ui->comboBox_StartFreq->count() != 0)
            _ui->comboBox_StartFreq->setCurrentIndex(0);
    }

    void GUIGlobalFrequencyDomainDialog::on_radioButton_13rdStandOct_toggled(bool checkState)
    {
        Q_UNUSED(checkState);
        if (!checkState) return;
        _ui->tabWidget->setCurrentIndex(0);
        _ui->lineEdit->setEnabled(false);
        _ui->lineEdit_Bandwidth->setEnabled(false);
        this->initStartFreqComboBox(Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandard1Of3rdOctave);
        this->initEndFreqComboBox(Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandard1Of3rdOctave);
        //设置界面数据
        if (_ui->comboBox_EndFreq->count() != 0)
            _ui->comboBox_EndFreq->setCurrentIndex(_ui->comboBox_EndFreq->count() - 1);
        if (_ui->comboBox_StartFreq->count() != 0)
            _ui->comboBox_StartFreq->setCurrentIndex(0);
    }

    void GUIGlobalFrequencyDomainDialog::on_radioButton_Exact_toggled(bool checkState)
    {
        Q_UNUSED(checkState);
        if (!checkState) return;
        _ui->tabWidget->setCurrentIndex(0);
        _ui->lineEdit->setEnabled(true);
        _ui->lineEdit_Bandwidth->setEnabled(false);
        this->initStartFreqComboBox(Acoustics::FITKGlobalFrequencyDomain::DomainType::DTExact1OfnthOctave);
        this->initEndFreqComboBox(Acoustics::FITKGlobalFrequencyDomain::DomainType::DTExact1OfnthOctave);
        //设置界面数据
        if (_ui->comboBox_EndFreq->count() != 0)
            _ui->comboBox_EndFreq->setCurrentIndex(_ui->comboBox_EndFreq->count() - 1);
        if (_ui->comboBox_StartFreq->count() != 0)
            _ui->comboBox_StartFreq->setCurrentIndex(0);
    }

    void GUIGlobalFrequencyDomainDialog::on_radioButton_Constant_toggled(bool checkState)
    {
        Q_UNUSED(checkState);
        if (!checkState) return;
        _ui->tabWidget->setCurrentIndex(1);
        _ui->lineEdit->setEnabled(false);
        _ui->lineEdit_Bandwidth->setEnabled(true);
        this->initStartFreqComboBox(Acoustics::FITKGlobalFrequencyDomain::DomainType::DTConstantBandWidth);
        this->initEndFreqComboBox(Acoustics::FITKGlobalFrequencyDomain::DomainType::DTConstantBandWidth);
        //设置界面数据
        if (_ui->comboBox_EndFreq->count() != 0)
            _ui->comboBox_EndFreq->setCurrentIndex(_ui->comboBox_EndFreq->count() - 1);
        if (_ui->comboBox_StartFreq->count() != 0)
            _ui->comboBox_StartFreq->setCurrentIndex(0);
    }

    void GUIGlobalFrequencyDomainDialog::initStartFreqComboBox(int type)
    {
        QStringList freq;
        if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandardOctave)
        {
            freq << "2" << "4" << "8" << "16" << "31.5" << "63" << "125" << "250" << "500" << "1000" << "2000" << "4000"
                << "8000" << "16000" << "32000" << "64000" << "128000";
        }
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandard1Of3rdOctave)
        {
            freq << "1.25" << "1.6" << "2" << "2.5" << "3.15" << "4" << "5" << "6.3" << "8" << "10"
                 << "12.5" << "16" << "20" << "25" << "31.5" << "40" << "50" << "63" << "80" << "100"
                 << "125" << "160" << "200" << "250" << "315" << "400" << "500" << "630" << "800" << "1000"
                 << "1250" << "1600" << "2000" << "2500" << "3150" << "4000" << "5000" << "6300" << "8000" << "10000"
                 << "12500" << "16000" << "20000" << "25000" << "32000" << "40000" << "50000" << "64000" << "80000" << "100000"
                 << "128000" << "160000";
        }
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTExact1OfnthOctave)
        {
            //默认值频率是1000
            const double f0 = 1000;
            const double n = _ui->lineEdit->text().toDouble();
            freq << "1000";
            int i = -1;
            double fc = f0;
            //小于1000的部分
            while (fc > 1.25)
            {
                fc = pow(2.0, i / n)*f0;
                freq.insert(0, QString::number(fc));
                i--;
            }
            //大于1000的部分
            i = 1; fc = f0;
            while (fc < 160000)
            {
                fc = pow(2.0, i / n)*f0;
                freq.append(QString::number(fc));
                i++;
            }
        }
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTConstantBandWidth)
        {
            _ui->lineEdit_StartFreq->setText(_ui->comboBox_StartFreq->currentText());
        }
        _ui->comboBox_StartFreq->clear();
        _ui->comboBox_StartFreq->addItems(freq);
        _ui->comboBox_StartFreq->update();
    }

    void GUIGlobalFrequencyDomainDialog::initEndFreqComboBox(int type)
    {
        QStringList freq;
        if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandardOctave)
        {
            freq << "2" << "4" << "8" << "16" << "31.5" << "63" << "125" << "250" << "500" << "1000" << "2000" << "4000"
                << "8000" << "16000" << "32000" << "64000" << "128000";
        }
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTStandard1Of3rdOctave)
        {
            freq << "1.25" << "1.6" << "2" << "2.5" << "3.15" << "4" << "5" << "6.3" << "8" << "10"
                << "12.5" << "16" << "20" << "25" << "31.5" << "40" << "50" << "63" << "80" << "100"
                << "125" << "160" << "200" << "250" << "315" << "400" << "500" << "630" << "800" << "1000"
                << "1250" << "1600" << "2000" << "2500" << "3150" << "4000" << "5000" << "6300" << "8000" << "10000"
                << "12500" << "16000" << "20000" << "25000" << "32000" << "40000" << "50000" << "64000" << "80000" << "100000"
                << "128000" << "160000";
        }
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTExact1OfnthOctave)
        {
            //默认值频率是1000
            const double f0 = 1000;
            const double n = _ui->lineEdit->text().toDouble();
            freq << "1000";
            int i = -1;
            double fc = f0;
            //小于1000的部分
            while (fc > 1.25)
            {
                fc = pow(2.0, i / n)*f0;
                freq.insert(0, QString::number(fc));
                i--;
            }
            //大于1000的部分
            i = 1; fc = f0;
            while (fc < 160000)
            {
                fc = pow(2.0, i / n)*f0;
                freq.append(QString::number(fc));
                i++;
            }
        }
        else if (type == Acoustics::FITKGlobalFrequencyDomain::DomainType::DTConstantBandWidth)
        {
            _ui->lineEdit_EndFreq->setText(_ui->comboBox_EndFreq->currentText());
        }
        _ui->comboBox_EndFreq->clear();
        _ui->comboBox_EndFreq->addItems(freq);
        _ui->comboBox_EndFreq->update();
    }
}

